package com.duoec.dw.lineage.service.analyser.from;

import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import com.alibaba.druid.sql.ast.statement.SQLLateralViewTableSource;
import com.duoec.dw.lineage.dto.MultiTableLineageDto;
import com.duoec.dw.lineage.dto.TableFieldDependencyDto;
import com.duoec.dw.lineage.dto.TableFieldLineageDto;
import com.duoec.dw.lineage.dto.TableLineageDto;
import com.duoec.dw.lineage.exceptions.LineageAnalyseException;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.LinkedHashSet;

/**
 * edw/edw_agents/ods/ods_edw_agents.ods_arm_user_career_ext.sql
 *
 * @author xuwenzhen
 */
@Service
public class LateralViewTableSourceAnalyser extends BaseTableSourceAnalyser<SQLLateralViewTableSource> {
    /**
     * 获取当前类处理的类型
     *
     * @return SQLTableSource子类类型
     */
    @Override
    public Class<SQLLateralViewTableSource> getTableSourceType() {
        return SQLLateralViewTableSource.class;
    }

    /**
     * 解析 from
     *
     * @param tableSource         需要解析的from
     * @param withAsTableLineages with-in
     * @return 当前select脚本的血缘关系
     */
    @Override
    public MultiTableLineageDto analyse(SQLLateralViewTableSource tableSource, MultiTableLineageDto withAsTableLineages) {
        MultiTableLineageDto fromTableLineages = hiveAnalyser.analyseFrom(tableSource.getTableSource(), null);

        MultiTableLineageDto multiTableLineages = new MultiTableLineageDto();
        TableLineageDto firstLineage = fromTableLineages.getFirst();
        if (firstLineage == null) {
            throw new LineageAnalyseException("无法获取到Lateral View！");
        }

        TableLineageDto lastNotLateralViewTable = new TableLineageDto();
        BeanUtils.copyProperties(firstLineage, lastNotLateralViewTable);
        LinkedHashSet<TableFieldLineageDto> fieldLineages = new LinkedHashSet<>();
        lastNotLateralViewTable.setFields(fieldLineages);
        multiTableLineages.add(lastNotLateralViewTable);

        SQLMethodInvokeExpr method = tableSource.getMethod();

        //Lateral View 的处理
        LinkedHashSet<TableFieldLineageDto> lateralFields = hiveAnalyser.analyseSelect(lastNotLateralViewTable, multiTableLineages, method);
        TableFieldLineageDto lateralField = lateralFields.iterator().next();
        LinkedHashSet<TableFieldDependencyDto> dependencies = lateralField.getDependencies();

        LinkedHashSet<TableFieldLineageDto> fields = new LinkedHashSet<>();
        tableSource.getColumns().forEach(col -> {
            if (col instanceof SQLIdentifierExpr) {
                TableFieldLineageDto field = new TableFieldLineageDto();
                field.setColName(((SQLIdentifierExpr) col).getName());
                field.setIndex(fields.size());
                field.setDependencies(dependencies);
                fields.add(field);
            } else {
                throw new LineageAnalyseException("暂未实现SQLLateralViewTableSource.column类型[" + col.getClass().getSimpleName() + "]的分析");
            }
        });

        //lateral view产生的table
        TableLineageDto tableLineage = new TableLineageDto();
        tableLineage.setLateralView(true);
        String alias = tableSource.getAlias();
        if (!StringUtils.isEmpty(alias)) {
            tableLineage.setAlias(alias);
        }
        tableLineage.setFields(fields);
        tableLineage.setDatabaseName(lastNotLateralViewTable.getDatabaseName());
        tableLineage.setTableName(lastNotLateralViewTable.getTableName());

        fromTableLineages.add(tableLineage);
        return fromTableLineages;
    }
}
